#ifndef Quaternion_h__
#define Quaternion_h__

typedef struct 
{
	double w; /* 1 */
	double x; /* i */
	double y; /* j */
	double z; /* k */
} Quaternion;


/* construct quaternion using values w,x,y,z. 
 * @param double w - coefficient for 1.
 * @param double x - coefficient for i.
 * @param double y - coefficient for j.
 * @param double z - coefficient for k.
 * @return: quaternion according to values.
 */
Quaternion Quaternion_fromValues( double w, double x, double y, double z );

/* construct quaternion from rotation axis and angle. 
 * @param Vector3d* v - rotation axis.
 * @param double angle - angle in rad.
 * @return: quaternion according to given axis angle.
 */
Quaternion Quaternion_fromAxisAngle( Vector3d* v, double angle );

/* construct quaternion from rotation axis and angle. 
 * @param double x - x value of axis.
 * @param double y - y value of axis.
 * @param double z - z value of axis.
 * @param double angle - angle in rad.
 * @return: quaternion according given axis angle.
 */
Quaternion Quaternion_fromAxisAngleValues( double x, double y, double z, double angle );

/* extract axis angle rotation from given quaternion 
 * @param Quaternion* q - given quaternion.
 * @param Vector3d* v - will hold axis of rotation extracted from quaternion q.
 * @param double* angle - will hold angle of rotation extracted from quaternion q.
 */
void Quaternion_toAxisAngle( Quaternion* q, Vector3d* v, double* angle );

/* multiply quaternion p by quaternion q.
 * p and q will not be modified.
 * @param Quaternion* p - left quaternion.
 * @param Quaternion* q - right quaternion.
 * @return p*q as quaternion.
 */
Quaternion Quaternion_multiply( Quaternion* p, Quaternion* q );

/* normalize given quaternion p; 
 * quaternion p will not be modified.
 * @param Quaternion* p - quaternion to be normalized.
 * @return: normalized quaternion.
 */
Quaternion Quaternion_normalized( Quaternion* p );
#endif // Quaternion_h__